package kr.co.thornbacksoft.mrnom;

import java.util.Random;

import android.util.Log;

public class World {
	static final int WORLD_WIDTH = 10;
	static final int WORLD_HEIGHT = 13;
	static final int SCORE_INCREMENT = 10;
	static final int SCORE_DECREMENT = 5;
	static final float TICK_INITIAL = 0.5f;
	static final float TICK_DECREMENT = 0.05f;

	public Snake snake;
	public Stain stain;
	public Item item;
	public Enemy enemy;
	public boolean gameOver = false;
	public int score = 0;

	boolean fields[][] = new boolean[WORLD_WIDTH][WORLD_HEIGHT];
	Random random = new Random();
	float tickTime = 0;
	static float tick = TICK_INITIAL;

	public World() {
		snake = new Snake();
		item = new Item();
		enemy = new Enemy();
		placeStain();
	}

	private void placeStain() {
		for (int x = 0; x < WORLD_WIDTH; x++) {
			for (int y = 0; y < WORLD_HEIGHT; y++) {
				fields[x][y] = false;
			}
		}

		int len = snake.parts.size();

		for (int i = 0; i < len; i++) {
			SnakePart part = snake.parts.get(i);
			fields[part.x][part.y] = true;
		}

		fields[enemy.x][enemy.y] = true;

		int stainX = random.nextInt(WORLD_WIDTH);
		int stainY = random.nextInt(WORLD_HEIGHT);

		while (true) {
			if (fields[stainX][stainY] == false)
				break;

			stainX += 1;

			if (stainX >= WORLD_WIDTH) {
				stainX = 0;
				stainY += 1;
				if (stainY >= WORLD_HEIGHT) {
					stainY = 0;
				}
			}
		}

		stain = new Stain(stainX, stainY, random.nextInt(3));
	}

	public void update(float deltaTime) {
		if (gameOver)
			return;

		tickTime += deltaTime;

		while (tickTime > tick) {
			tickTime -= tick;

			snake.advance();

			if (snake.checkBitten()) {
				gameOver = true;
				return;
			}

			SnakePart head = snake.parts.get(0);

			if (head.x == stain.x && head.y == stain.y) {
				score += SCORE_INCREMENT;

				snake.eat();

				getItem();

				if (snake.parts.size() == WORLD_WIDTH * WORLD_HEIGHT) {
					gameOver = true;
					return;
				} else {
					placeStain();
				}

				if (score % 100 == 0 && tick - 1 > 0) {
					tick -= TICK_DECREMENT;
				}
			}

			enemy.advanced();

			if (enemy.x == stain.x && enemy.y == stain.y) {
				score -= SCORE_INCREMENT;

				snake.spit();

				if (snake.parts.size() == 1) {
					gameOver = true;
					return;
				} else {
					placeStain();
				}
			}
		}
	}

	private void getItem() {
		int itemType = random.nextInt(4);

		if (itemType != 0)
			item.type = itemType;
	}

	public void useItem() {
		if (item.type == Item.SPEED_UP && tick - 1 > 0) {
			Log.v("item", "before speedup: " + tick);
			tick -= TICK_DECREMENT;
			Log.v("item", "after speedup: " + tick);
		}
		if (item.type == Item.SPEED_DOWN && tick + 1 < 10) {
			Log.v("item", "before speeddown: " + tick);
			tick += TICK_DECREMENT;
			Log.v("item", "after speeddown: " + tick);
		}
		if (item.type == Item.LIFE_UP) {
			Log.v("item", "before lifeup: " + snake.parts.size());
			snake.eat();
			Log.v("item", "after lifeup: " + snake.parts.size());
		}

		item.type = Item.NONE;
	}
}
